#include "input.hpp"

int ManInput::scanKeyboard(){

	int in;

	struct termios new_settings;
	struct termios stored_settings;
	
	//设置终端参数
	tcgetattr(0,&stored_settings);
	new_settings = stored_settings;
	new_settings.c_lflag &= (~ICANON);
	new_settings.c_cc[VTIME] = 0;
	tcgetattr(0,&stored_settings);
	new_settings.c_cc[VMIN] = 1;
	tcsetattr(0,TCSANOW,&new_settings);
	in = getchar();
	tcsetattr(0,TCSANOW,&stored_settings);

	return in;

}

int ManInput::getChar(){
	fd_set rfds;
	struct timeval tv;
	int ch = 0;
	FD_ZERO(&rfds);
	FD_SET(0, &rfds);
	tv.tv_sec = 0;
	tv.tv_usec = 10; //设置等待超时时间
	if (select(1, &rfds, NULL, NULL, &tv) > 0) //检测键盘是否有输入
	{
		ch = getchar(); 
	}
	return ch;
}

void ManInput::loop(){
	int input = 0;
	bool quit = false;
	while(!m_quit){
		//input = getChar();
		input = scanKeyboard();
		if(input != 0){
			m_callback(input,m_data,&quit);
			if(quit == true)
				m_quit = true;
		}
	}
}

void ManInput::threadFunc(ManInput* ptr){
	ptr->loop();
}

ManInput::ManInput(int (*callback)(int,void *,bool *),void * data){
	m_callback = callback;
	m_data = data;
	m_quit = false;
	m_thread = thread(threadFunc,this);
}

ManInput::~ManInput(){
	m_quit = true;
	
	if (m_thread.joinable()){
		pthread_cancel(m_thread.native_handle());
		m_thread.join();
	}

}
